 # 包含公共函数和工具类

import random
import string
import os, sys
import math
import numpy as np
import pandas as pd
from datetime import datetime
import csv

questionnaireCount = 121
###################产生2个以上随机整数###################
###################第一个数随机产生，第二个使用平均数求出###################
#count 数字的个数
#average 平均数
#begin 起始区间
#end 结束区间

def int_random_old (average, begin, end):

    numarr = [];

    while (1):

        num_first = random.randint(begin, end);
        num_second = average * 2 - num_first;

        if (num_second >= begin and num_second <= end):
            numarr.append(num_first);
            numarr.append(num_second);
            break
        # else:
            # print("num_second: " + str(num_second))

    return numarr;


def int_random (average, begin, end):

    #print "wzh_random"
    # numarr = [0 for x in range(2)];
    numarr = [];
    i = 0;
    # while (1):
 
    #   num_first = random.randrange(begin, end);
    num_first = random.randint(begin, end);

    #第二个数
    num_second = average * 2 - num_first;

    numarr.append(num_first);
  
   
    if (num_second >= begin and num_second <= end):  
        numarr.append(num_second);
    else:
        # 继续分配,分为三个数
        # 12 -1 ==11 ; 11+4 = 15
        # 15 -3 ==12 ; 12+5 = 17
        rest_val_temp = average * 3 - num_first

        restTwo = re_random(rest_val_temp, begin, end,average)
        numarr.extend(restTwo)

    return numarr;

def re_random (rest_val, begin, end,average):
    numarr = [];
    random_number = random.uniform(0,1)
    if rest_val <= 10:
        if random_number <= 0.5:
            # 大值与小值
            numarr.append(end)
            numarr.append(rest_val - end)
        else:
            # 平均分
            if (rest_val % 2) == 0:
                #偶数
                numarr.append(rest_val/2)
            else:
                #奇数
                numarr.append(rest_val//2)
                numarr.append(rest_val//2 + 1)
    else:
        rest_val2 = rest_val + average
        mean_temp =    rest_val2//3
        numarr.append(mean_temp)
        numarr.append(mean_temp)
        numarr.append(rest_val2-mean_temp*2)

    """     
    for i in range(len(numarr)):
        if numarr[i] > end: 
    """

            

    return numarr;





###################产生随机数###################
###################第一个数随机产生，第二个使用平均数求出###################
#count 数字的个数
#average 平均数
#begin 起始区间
#end 结束区间
def float_random (count, average, begin, end):

    #print "wzh_random"
    numarr = [0 for x in range(2)];
    i = 0;
    while (1):
 
      num = random.uniform(begin, end);
      #取两位小数
      num_first = round(num, 2);

      #第二个数
      num_second = average * 2 - num_first;

      if (num_second >= begin and num_second <= end):
          numarr[i] = num_first;
          i = i + 1;
          numarr[i] = num_second;
          break

    return numarr;



###################写文件###################
def write_file (filename, content):
    fo = open (filename, "rb+");
    fo.write(bytes(content,'utf-8'));
    # fo.write(content);
    fo.close();

def show_list (list):
    for i in list:
        print(i, end=' ')
    print();
    
    t_sum = 0   
    t_average = 0.0

    t_sum = sum(list)
    t_average = round(t_sum/questionnaireCount,4)

    print("列表的和：" + str(t_sum))
    print("数量："+ str(len(list)));
    print("列表的平均数：" + str(t_average))

###################主函数调用产生整形随机数###################

def dataModify(list):
    # 生成一个1到4到随机数


    lastIndex = len(list) - 1
    num_begin = random.randint(1, 4);

    """ 
    num_list = [] 
    num_list.append(num_begin)
    num_list.append(num_begin+1)
    num_list.append(num_begin+2) """

    swapPositions(list,num_begin,lastIndex-num_begin)
    swapPositions(list,num_begin+1,lastIndex-num_begin-1)
    swapPositions(list,num_begin+2,lastIndex-num_begin-2)

    return list
def swapPositions(list, pos1, pos2):
     
    list[pos1], list[pos2] = list[pos2], list[pos1]
    return list


# 按照预期的平均值产生整形随机数
def generateRandomNumsByExpectAverage(ava):
    
    realAverage = ava

    begin = math.floor(ava)
    end = math.ceil(ava) 
    
    # 对平均数取整以后，要对平均数进行调整 5的话不出现begin=2, 3的话end =4
    average = round(realAverage)
    print(str(realAverage) + " >>>>>> " + str(average) )
    count = questionnaireCount;
    # begin = 3;
    # end = 4;
    numarr_count = 0;
    numarr = [0 for x in range(count)];

    
    print("begin："+ str(begin))
    print("end："+ str(end))

    # for i in range (count // 2):
    while(numarr_count < count):
        templist = int_random_old (average, begin, end)
        j = 0;
        for j in range (len(templist)):
            # numarr_count 有可能大于120
            if numarr_count < count:
                numarr[numarr_count] = templist[j]
                numarr_count += 1
            else:
                print('注意!!!!!: numarr_count: ' + str(numarr_count))
                break;

    
    # print("修正前 ######：")
    # show_list (numarr)

    # 数据修正开始
    #if (count % 2) != 0:
     #   numarr[count-1] = random.randint(begin, end);

    t_average2 = round(sum(numarr)/count,4)
    # 平均数差值
    gapValue = round( realAverage - t_average2,4)
    if(  gapValue != 0):
        # 差了多少没有分配
        undistributed = round(count * gapValue,4)
        print("undistributed: " + str(undistributed))
        # 四舍五入取整
        undistributed = round(undistributed)

        # 分配到每个数里去,多退少补
        if(undistributed > 0):
            for x in range(len(numarr)):
                # undistributed 用完的时候跳出
                if(undistributed <= 0):
                    print("undistributed 剩余: " + str(undistributed))
                    break;
                if (numarr[x] < end):
                    numarr[x]  +=1
                    undistributed -=1
        else:
             for x in range(len(numarr)):
                # undistributed 用完的时候跳出
                if(undistributed >= 0):
                    print("undistributed 剩余: " + str(undistributed))
                    break;
                if (numarr[x] > begin or numarr[x] == 5):
                    numarr[x]  -=1
                    undistributed +=1
    # 从小到大排序
    numarr = sorted(numarr)
    # 数据打乱
    # random.shuffle(numarr);

    # 排序以后在spss里分析，信度会过高，效度分析时关联性太强，无法显示KMO值，因此要稍微弄乱一点
    # 随机在前五 和 倒数前五个数中 分别抽取3个， 相互调换位置
    numarr = dataModify(numarr)
    return numarr;

# 按照预期的平均值产生实型随机数
def test_random_float():
    count = 40;
    average = 402;
    begin = 363;
    end = 429;
    numarr_count = 0;
    numarr = [0 for x in range(count)];
    for i in range (count // 2):
        list = float_random (40, 402, 363, 429)
        j = 0;
        for j in range (len(list)):
             numarr[numarr_count] = list[j];
             numarr_count += 1;
    content = '';
    #打乱排序
    print("数据未打乱：");
    show_list (numarr)
    random.shuffle(numarr);
    print("数据打乱：");
    show_list (numarr)
    for i in numarr:
        content = content + ' ' + str(i);
    #print content;
    #追加写入文件
    filename = "test2.txt";
    print("文件名称：",filename);
    write_file (filename, content)
    write_file (filename, "\n");


def save_data_to_excel(data,dest_dir,file_name='newfile',dimensions=None):

     # 获取当前日期时间作为前缀
    timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")    

    # 构建完整的文件名
    dest = os.path.join(dest_dir, f"{timestamp}_{file_name}.xlsx")

    # 将数据转换为DataFrame
    df = pd.DataFrame(data)

    # 添加维度标题行
    if dimensions:
        # 将维度作为第一行的列标题
        df.columns = dimensions

    # 创建保存目录（如果不存在）
    os.makedirs(os.path.dirname(dest), exist_ok=True)

    # 将DataFrame保存为Excel文件
    df.to_excel(dest, index=False)

def save_data_to_csv_with_dimensions(sample_datas,csv_filename,dimensions = None):
    # 获取当前日期时间作为前缀
    timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")
    # 打开CSV文件进行写入
    with open( f"dest/{timestamp}_{csv_filename}.csv", mode='w', newline='') as file:
        writer = csv.writer(file)

        # 写入CSV文件的标题行，列名为维度名称
        writer.writerow(dimensions)

        # 逐行写入每个维度的数据
        for data_row in sample_datas:
            writer.writerow(data_row)

def getFilePathNameWithTimeStr(file_name,dest_dir):

    # 获取当前日期时间作为前缀
    timestamp = datetime.now().strftime("%Y%m%d-%H%M%S")    

    # 构建完整的文件名
    dest = os.path.join(dest_dir, f"{timestamp}_{file_name}.xlsx")

    return dest

def get_first_cell(data_from_sheet,column_name: str,):

    # 获取指定列名下的第一个单元格的值
    first_cell_value = data_from_sheet[column_name].iloc[0]

    return first_cell_value